﻿using SerialCommunication;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RfidCompareWin
{

    public partial class Form1 : Form
    {
        private string oldFilePath;//老的excel的路径
        private SettingsManager _settingsManager;

        SerialCommunicator communicator;//通讯串口
        CancellationTokenSource cts;//线程取消标志

        ScreenOCRTool ocrTool;
        public Form1()
        {
            InitializeComponent();
            RefreshComPorts();
            _settingsManager = new SettingsManager();
            m_bSendData.Enabled = false;
            LoadSettings();
        }
        // 保存设置到INI文件
        private void SaveSettings()
        {
            try
            {
                _settingsManager.WriteValue("UI", "SheetName", m_tbSheetName.Text);
                _settingsManager.WriteValue("UI", "Column", m_tbCol.Text);
                _settingsManager.WriteValue("UI", "FirstChecked", m_cbFist.Checked ? "1" : "0");

               // MessageBox.Show("设置已保存", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存设置时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Logger.Instance.Log(ex.Message,LogLevel.Error);
            }
        }

        // 从INI文件加载设置
        private void LoadSettings()
        {
            try
            {
                m_tbSheetName.Text = _settingsManager.ReadValue("UI", "SheetName", "");
                m_tbCol.Text = _settingsManager.ReadValue("UI", "Column", "");
                m_cbFist.Checked = _settingsManager.ReadValue("UI", "FirstChecked", "0") == "1";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载设置时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Logger.Instance.Log(ex.Message, LogLevel.Error);
            }
        }

        private void OpenExcel_Click(object sender, EventArgs e)
        {
            var path = ExcelReader.SelectExcelFile();
            if (path == string.Empty)
            {
                MessageBox.Show("未选择文件");
                return;
            }
            lb_excelPath.Text = "文件:"+path;
            SaveSettings();
            oldFilePath = path;
            m_readCount.Text = $"正在读取{m_tbSheetName.Text}页,列{m_tbCol.Text}的数据";

            string[] columnData = ExcelReader.ReadExcelColumn(path, m_tbSheetName.Text, m_tbCol.Text,m_cbFist.Checked);

            foreach (string value in columnData)
            {
                m_barlist.Items.Add(value);
            }
            m_readCount.Text = $"一共读取了 {m_barlist.Items.Count} 行数据";
        }
        /// <summary>
        /// 统计 ListBox 中每行文本的非空行数（处理包含换行符的项）
        /// </summary>
        /// <param name="listBox">要统计的 ListBox 控件</param>
        /// <returns>非空行的总数量</returns>
        public int CountNonEmptyLines(ListBox listBox)
        {
            int count = 0;

            foreach (var item in listBox.Items)
            {
                if (item == null) continue;

                string[] lines = item.ToString().Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string line in lines)
                {
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        count++;
                    }
                }
            }

            return count;
        }
        /// <summary>
        ///  打开串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void m_OpenCom_Click(object sender, EventArgs e)
        {
            try
            {
                communicator = new SerialCommunicator(comboBoxPorts.Text,9600,128);
                           
                // 注册数据接收事件
                communicator.DataReceived += (sender, e) =>
                {
                    Trace.WriteLine($"[接收事件] 收到 {e.Data.Length} 字节数据");

                    // 尝试将接收到的字节数据转换为字符串(根据实际情况调整编码)
                    string message = Encoding.ASCII.GetString(e.Data);
                    if (e.Data.Length==1)
                    {
                        return;
                    }
                
                    if (m_reBarList.InvokeRequired)
                    {
                        m_reBarList.Invoke(new Action(() =>
                        {
                            string[] lines = message.Split('\n');                         
                            m_reBarList.Items.AddRange(lines);//注意ui
                            lb_recvcount.Text = CountNonEmptyLines(m_reBarList).ToString();
                        }));
                    }
                    else
                    {
                        string[] lines = message.Split('\n');
                        m_reBarList.Items.AddRange(lines);//注意ui
                        lb_recvcount.Text = CountNonEmptyLines(m_reBarList).ToString();
                    }

                    Trace.WriteLine($"[接收内容] {message}");
                };

                // 注册错误事件
                communicator.ErrorOccurred += (sender, e) =>
                {
                    Trace.WriteLine($"[错误事件] {e.ErrorMessage}");

                    if (m_lbProcess.InvokeRequired)
                    {
                        m_lbProcess.Invoke(new Action(() =>
                        {

                            m_lbProcess.Text = $"[错误事件] {e.ErrorMessage}"; ;//注意ui
                        }));
                    }
                    else
                    {
                        m_lbProcess.Text = $"[错误事件] {e.ErrorMessage}"; ;//注意ui
                    }

                    Logger.Instance.Log($"[错误事件] {e.ErrorMessage}", LogLevel.Error);

                };
                // 注册发送进度事件
                communicator.ProcessOccurred += (sender, e) =>
                {
                    Trace.WriteLine($"[进度事件] {e.ProcessMessage}");

                    if (m_lbProcess.InvokeRequired)
                    {
                        m_lbProcess.Invoke(new Action(() =>
                        {
                           
                            m_lbProcess.Text=e.ProcessMessage;//注意ui
                        }));
                    }
                    else
                    {
                        m_lbProcess.Text = e.ProcessMessage;//注意ui
                    }

                    Logger.Instance.Log($"[下发进度事件] {e.ProcessMessage}", LogLevel.Info);

                };
                // 注册接收进度事件
                communicator.AcceptProcessOccurred += (sender, e) =>
                {
                    Trace.WriteLine($"[接收数据事件] {e.ProcessMessage}");

                    if (m_lbAcceptProcess.InvokeRequired)
                    {
                        m_lbAcceptProcess.Invoke(new Action(() =>
                        {

                            m_lbAcceptProcess.Text = e.ProcessMessage;//注意ui
                        }));
                    }
                    else
                    {
                        m_lbAcceptProcess.Text = e.ProcessMessage;//注意ui
                    }

                    Logger.Instance.Log($"[下发进度事件] {e.ProcessMessage}", LogLevel.Info);

                };

                cts =new CancellationTokenSource();
                await communicator.OpenAsync(cts.Token);
                if (communicator._serialPort.IsOpen)
                {
                    m_bSendData.Enabled = true;
                    labelStatus.Text = "通讯串口已打开";
                    m_OpenCom.Enabled = false;
                }
                else
                {
                    m_bSendData.Enabled = false;
                    labelStatus.Text = "通讯串口未打开";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Logger.Instance.Log($"{ex.Message}", LogLevel.Error);

            }
        }


        public static byte[] ConvertListToBytes(List<string> liststr)
        {
            List<byte> byteList = new List<byte>();

            foreach (var str in liststr)
            {
                byteList.AddRange(Encoding.ASCII.GetBytes(str));
            }

            return byteList.ToArray();
        }
        //下发数据
        private void m_bSendData_Click(object sender, EventArgs e)
        {
            m_lbProcess.Text = "|";
            //string largeMessage = new string('X', 10240); // 10KB数据
            List<string> list = new List<string>(); //
            //for (int i = 0; i < 100; i++)
            //{
            //    list.Add($"{i} xxx\n");
            //}
             foreach (string value in m_barlist.Items)
            {
                list.Add(value+"\n");
            }
            byte[] data = ConvertListToBytes(list);
            Trace.WriteLine($"==>send size:{data.Length}");
            cts = new CancellationTokenSource(30000);//30秒超时失败

            // 发送数据 ,接收端必须收到数据后返回接收成功才能继续
            Task sendTask = Task.Run(async () =>
            {
                bool success = await communicator.SendDataAsync(data, cts.Token);
                Trace.WriteLine($"数据发送 {(success ? "成功" : "失败")}");
            }, cts.Token);



        }
        //保存list数据到excel 每行数据用'\n'分割
        private void m_btSave_Click(object sender, EventArgs e)
        {
            if (m_reBarList.Items.Count == 0)
            {
                MessageBox.Show("ListView中没有数据可导出！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // 创建保存对话框
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Excel文件 (*.xlsx)|*.xlsx|所有文件 (*.*)|*.*";
            saveFileDialog.Title = "保存Excel文件";

            //读取ini保存的前缀名 prefix
            string prefix =  _settingsManager.ReadValue("UI", "prefix", "");
            // 生成默认文件名（当前日期时间，精确到秒）
            string defaultFileName = prefix+" "+DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".xlsx";
            saveFileDialog.FileName = defaultFileName;

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                ExcelReader.ExportToExcel(saveFileDialog.FileName, m_reBarList);
            }
        }

        private void m_btClearBar_Click(object sender, EventArgs e)
        {
            m_barlist.Items.Clear();
        }

        private void m_btClearRevBar_Click(object sender, EventArgs e)
        {
            m_reBarList.Items.Clear();
        }
        //刷新串口列表
        private void RefreshComPorts()
        {
            try
            {
                // 清空当前列表
                comboBoxPorts.Items.Clear();

                // 获取系统中所有可用的COM端口
                string[] ports = SerialPort.GetPortNames();

                if (ports.Length == 0)
                {
                    comboBoxPorts.Items.Add("未发现可用串口");
                    comboBoxPorts.SelectedIndex = 0;
                    labelStatus.Text = "未发现可用的COM端口";
                    return;
                }

                // 按端口号排序
                Array.Sort(ports, (a, b) =>
                {
                    int aNum, bNum;
                    if (int.TryParse(a.Substring(3), out aNum) && int.TryParse(b.Substring(3), out bNum))
                    {
                        return aNum.CompareTo(bNum);
                    }
                    return a.CompareTo(b);
                });

                // 添加到ComboBox
                foreach (string port in ports)
                {
                    comboBoxPorts.Items.Add(port);
                }

                // 默认选择第一个端口
                comboBoxPorts.SelectedIndex = 0;

                labelStatus.Text = $"已加载 {ports.Length} 个COM端口";
            }
            catch (Exception ex)
            {
                labelStatus.Text = $"获取COM端口列表时出错: {ex.Message}";
                Logger.Instance.Log($"{labelStatus.Text}", LogLevel.Error);

            }
        }
        //用户取消下发任务
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                cts.Cancel();
            }
            catch (Exception ex) {
                MessageBox.Show(ex.Message);
                Logger.Instance.Log($"{ex.Message},{ex.StackTrace}", LogLevel.Error);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveSettings();
            communicator?.Dispose();
        }

        private void bt_SaveCompare_Click(object sender, EventArgs e)
        {
            if (m_reBarList.Items.Count == 0)
            {
                MessageBox.Show("ListView中没有数据可导出！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (oldFilePath == null)
            {
                MessageBox.Show("没有指定源excel文件的路径", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (m_tbSheetName.Text == "")
            {
                MessageBox.Show("没有指定sheet页名称", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (m_tbCol.Text == "")
            {
                MessageBox.Show("没有指定列名", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            // 创建保存对话框
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Excel文件 (*.xlsx)|*.xlsx|所有文件 (*.*)|*.*";
            saveFileDialog.Title = "保存Excel文件";
            //读取ini保存的前缀名 prefix
            string prefix = _settingsManager.ReadValue("UI", "prefix", "");
            // 生成默认文件名（当前日期时间，精确到秒）
            string defaultFileName = prefix+" "+ DateTime.Now.ToString("yyyyMMdd_HHmmss") + "副本.xlsx";
            saveFileDialog.FileName = defaultFileName;

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                ExcelReader.ExportToExcel(oldFilePath,saveFileDialog.FileName, m_reBarList,m_tbCol.Text,m_tbSheetName.Text);
            }
        }
        //提交表单
        private async void bt_Submit_Click(object sender, EventArgs e)
        {
            //if (m_reBarList.Items.Count == 0)
            //{
            //    MessageBox.Show("ListView中没有数据可提交！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //    return;
            //}
            // 创建OCR工具实例
             ocrTool = new ScreenOCRTool();

            // 设置感兴趣的文本
            ocrTool.SetInterestedTexts(new[] { "请输入" });

            // 设置只捕获特定区域（可选）
            ocrTool.SetCaptureRegion(new Rectangle(0, 0, 1920, 1080));

            // 设置识别间隔（可选）
            ocrTool.SetCaptureInterval(1000); // 500毫秒

            // 注册结果事件
            ocrTool.OcrResultAvailable += (sender, e) =>
            {
                Trace.WriteLine($"识别完成，找到{e.InterestedRegions.Count}个感兴趣区域");

                foreach (var region in e.InterestedRegions)
                {
                    Trace.WriteLine($"文本: {region.Text}, 位置: {region.Rect}");
                    // 要输入的内容
                    string textToType = "Hello123World!";
                    var inputBoxX = region.Rect.Center.X;
                    var inputBoxY = region.Rect.Center.Y;
                    // 点击输入框并输入内容
                   MouseKeyboardSimulator.ClickAndType((int)inputBoxX, (int)inputBoxY, textToType);
                }
            };

            // 注册错误事件
            ocrTool.ErrorOccurred += (sender, error) =>
            {
                Console.WriteLine($"OCR错误: {error}");
            };

            // 启动识别
            await ocrTool.StartAsync();

            // 程序运行一段时间后停止
            await Task.Delay(30000); // 运行30秒
            ocrTool.Stop();
        }

        private void bt_stopSubmit_Click(object sender, EventArgs e)
        {
            if (ocrTool != null) { ocrTool.Stop(); }
           
        }
    }
}
